import { forwardRef, InputHTMLAttributes, ReactNode, useId } from 'react';
import MaskedInput from 'react-text-mask';

import { ReactComponent as CrossIconMobile } from '@/assets/images/buy/cross.svg';
import { ReactComponent as CrossIcon } from '@/assets/images/shared/icon-close.svg';
import { ReactComponent as SearchIcon } from '@/assets/images/shared/icon-search.svg';
import { ReactComponent as PromoIcon } from '@/shared/icons/icon-promo.svg';
import cn from 'classnames';

import cs from './Input.module.scss';

type IconVariants = 'search' | 'clear' | 'promo';
function isReactNode(child: ReactNode | IconVariants): child is ReactNode {
  return typeof child !== 'string';
}

const Icons: Record<IconVariants, JSX.Element> = {
  search: <SearchIcon />,
  clear: (
    <>
      <CrossIcon className={cs.desktop} /> <CrossIconMobile className={cs.mobile} />
    </>
  ),
  promo: <PromoIcon />,
};

export const Input = forwardRef(
  (
    {
      label,
      mask,
      guide,
      left,
      right,
      className,
      register,
      type,
      name,
      info,
      clearing,
      isInvalid,
      onLeftClick,
      onRightClick,
      ...props
    }: {
      label?: string;
      left?: IconVariants | ReactNode;
      right?: IconVariants | ReactNode;
      info?: ReactNode;
      mask?: unknown[];
      guide?: boolean;
      className?: string;
      register?: any;
      clearing?: any;
      isInvalid?: boolean;
      name?: any;
      onLeftClick?: () => void;
      onRightClick?: () => void;
    } & InputHTMLAttributes<HTMLInputElement>,
    ref,
  ) => {
    const id = useId();
    return (
      <span className={cs.textarea}>
        {!!label && (
          <label className={cs.label} htmlFor={id}>
            {label}
          </label>
        )}
        <label className={cn(cs.input_container, isInvalid && cs.invalid, className)} htmlFor={id}>
          {!!left && (
            <div className={cn(cs.icon, onLeftClick && cs.active_icon)} onClick={() => onLeftClick?.()}>
              {isReactNode(left) ? left : Icons[left]}
            </div>
          )}
          {mask ? (
            <MaskedInput
              className={cn(cs.input)}
              guide={guide}
              id={id}
              mask={mask}
              onFocus={() => clearing()}
              ref={ref}
              type={type || 'text'}
              {...register(name)}
              {...props}
            />
          ) : (
            <input
              className={cn(cs.input)}
              id={id}
              onFocus={() => clearing()}
              ref={ref}
              type={type || 'text'}
              {...register(name)}
              {...props}
            />
          )}

          {right && (
            <div className={cn(cs.icon, onRightClick && cs.active_icon)} onClick={() => onRightClick?.()}>
              {isReactNode(right) ? right : Icons[right]}
            </div>
          )}
        </label>
        {isInvalid && <div className={cs.error}>Некорректный формат</div>}
        {!!info && <div className={cs.info}>{info}</div>}
      </span>
    );
  },
);
